package com.dmagic.cms.common.controller;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jodd.servlet.ServletUtil;

import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.dmagic.cms.common.exception.ServiceException;
import com.dmagic.cms.common.service.CommonService;
import com.dmagic.cms.common.spring.SpringContextHolder;
import com.dmagic.cms.common.util.DateUtil;
import com.dmagic.cms.common.util.FileUtil;
import com.dmagic.cms.common.util.JsonUtil;
import com.dmagic.cms.common.util.NumberUtil;
import com.dmagic.cms.common.util.ServletUtils;
import com.dmagic.cms.common.util.StringUtil;
import com.dmagic.cms.entity.UploadFileInfo;
import com.dmagic.cms.service.BaseService;

public class CommonController {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	protected final String INFORMATION = "Information";

	protected final String WARNNING = "Warnning";

	protected final String ERROR = "Error";

	protected final String SUCCESS = "Success";

	protected final String DATE_FORMAT = "yyyy-MM-dd HH:mm";

	@Autowired
	private BaseService baseService;

	public CommonService getComonService() {
		return SpringContextHolder.getBean(CommonService.class);
	}

	public String getDateFormatNo() {
		// String r = RandomStringUtils.randomNumeric(10);
		// return r;
		return DateUtil.dateToString(new Date(), "yyyyMMddhhmmss");
	}

	@RequestMapping("upload")
	@ResponseBody
	public String upload(HttpServletRequest request) {
		MultipartFile file = ((MultipartHttpServletRequest) request).getFile("Filedata");
		String uploadFileSetId = request.getParameter("uploadFileSetId");
		try {
			Long uploadFileSetInfoId = StringUtil.isBlank(uploadFileSetId) ? null : Long
					.valueOf(uploadFileSetId);
			UploadFileInfo fileInfo = baseService.upload((CommonsMultipartFile) file, uploadFileSetInfoId);
			return JsonUtil.toJson(fileInfo);
		} catch (ServiceException e) {
			logger.error("", e);
			return e.getMessage();
		}
	}

	@RequestMapping("upload2")
	@ResponseBody
	public String upload2(HttpServletRequest request) {
		MultipartFile file = ((MultipartHttpServletRequest) request).getFile("upload");
		UploadFileInfo fileInfo = null;
		String callback = request.getParameter("CKEditorFuncNum");
		try {
			fileInfo = baseService.upload((CommonsMultipartFile) file, null);
			String srcUrl = request.getContextPath() + "/home/imagesrc.do?fileInfoId="
					+ fileInfo.getUploadFileInfoId();
			return "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction(" + callback
					+ ",'" + srcUrl + "')</script>";
		} catch (ServiceException e) {
			logger.error("", e);
			return "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction(" + callback
					+ ",'" + "','" + e.getMessage() + "')</script>";
		}
	}

	@RequestMapping("downloadFile")
	public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
		String fileInfoId = request.getParameter("uploadFileInfoById");
		Long uploadFileInfoById = NumberUtil.toLong(fileInfoId);
		UploadFileInfo uploadFileInfo = baseService.getUploadFileInfo(uploadFileInfoById);
		String path = uploadFileInfo.getLocation();
		if (StringUtil.startsWith(path, "\\")) {
			path = "\\" + path;
		}
		File file = FileUtil.getFile(path);
		/**
		 * if file exist
		 */
		if (file.exists()) {
			response.reset();
			ServletUtils.setFileDownloadHeader(request, response, uploadFileInfo.getFileName());
			int fileLength = (int) file.length();
			response.setContentLength(fileLength);
			/**
			 * file size bigger that 0
			 */
			if (fileLength != 0) {

				InputStream inStream = null;
				ServletOutputStream outStream = null;
				try {
					inStream = new FileInputStream(file);
					outStream = response.getOutputStream();

					byte[] buf = new byte[4096];
					int readLength;
					while (((readLength = inStream.read(buf)) != -1)) {
						outStream.write(buf, 0, readLength);
					}
				} catch (FileNotFoundException e) {
					logger.error(e.getMessage(), e);
				} catch (IOException ioe) {
					logger.error(ioe.getMessage(), ioe);
				} finally {
					try {
						inStream.close();
						outStream.flush();
						outStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}

				}
			}
		}
	}

	@RequestMapping("deleteUploadFile")
	@ResponseBody
	public String deleteUploadFile(@RequestParam("uploadFileInfoId") Long uploadFileInfoId) {
		baseService.deleteUploadFileInfoByUploadFileInfoId(uploadFileInfoId);
		return "Successful.";
	}

	@RequestMapping("imagesrc")
	public void imagesrc(@RequestParam Long fileInfoId, HttpServletResponse reponse) {
		UploadFileInfo fileInfo = baseService.getUploadFileInfo(fileInfoId);
		String imgPath = fileInfo.getLocation();
		File imgFile = FileUtil.getFile(imgPath);
		byte[] buf = new byte[4096];
		DataInputStream dis = null;
		OutputStream out = null;
		try {
			out = reponse.getOutputStream();
			dis = new DataInputStream(new FileInputStream(imgFile));
			while (dis.read(buf) > 0) {
				out.write(buf);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
				if (dis != null)
					dis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@RequestMapping("imagesrc2")
	public void imagesrc2(@RequestParam Long fileInfoId, @RequestParam Integer width,
			@RequestParam Integer height, HttpServletResponse reponse) {
		UploadFileInfo fileInfo = baseService.getUploadFileInfo(fileInfoId);
		String imgPath = fileInfo.getLocation();

		OutputStream out = null;
		try {
			out = reponse.getOutputStream();
			scale(imgPath, out, height, width, true);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 缩放图像（按高度和宽度缩放）
	 * 
	 * @param srcImageFile
	 *            源图像文件地址
	 * @param out
	 *            缩放后的图像
	 * @param height
	 *            缩放后的高度
	 * @param width
	 *            缩放后的宽度
	 * @param bb
	 *            比例不对时是否需要补白：true为补白; false为不补白;
	 */
	public final void scale(String srcImageFile, OutputStream out, int height, int width, boolean bb) {
		try {
			double ratio = 0.0; // 缩放比例
			File f = new File(srcImageFile);
			BufferedImage bi = ImageIO.read(f);
			Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);
			// 计算比例
			if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
				if (bi.getHeight() > bi.getWidth()) {
					ratio = (new Integer(height)).doubleValue() / bi.getHeight();
				} else {
					ratio = (new Integer(width)).doubleValue() / bi.getWidth();
				}
				AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(ratio, ratio),
						null);
				itemp = op.filter(bi, null);
			}
			if (bb) {// 补白
				BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
				Graphics2D g = image.createGraphics();
				g.setColor(Color.white);
				g.fillRect(0, 0, width, height);
				if (width == itemp.getWidth(null))
					g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2, itemp.getWidth(null),
							itemp.getHeight(null), Color.white, null);
				else
					g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0, itemp.getWidth(null),
							itemp.getHeight(null), Color.white, null);
				g.dispose();
				itemp = image;
			}
			ImageIO.write((BufferedImage) itemp, "JPEG", out);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("getUploadFile")
	@ResponseBody
	public String getFileInfoByFileSetId(@RequestParam Long fileSetInfoId) {
		List<UploadFileInfo> fileInfos = baseService
				.getUploadFileInfoListByUploadFileSetInfoId(fileSetInfoId);
		return JsonUtil.toJson(fileInfos);
	}

	@RequestMapping("setMainFile")
	@ResponseBody
	public String setMainFile(@RequestParam Long uploadFileInfoId) {
		baseService.setMainFileByFileInfoId(uploadFileInfoId);
		return "Successful.";
	}
}
